const { Existing, AuthFailed, NotFound } = require('../core/http-exception')
const { redis, generateToken, isModelOne, getLike } = require('../common')
const { Comment, Article, User, Like } = require('../models')
const { ADMIN } = require('../middleware/auth')
const { Op } = require('sequelize')
const xss = require('xss')

class CommentController {
  static async create(data, auth) {
    const key = `article_comment_${auth.id}_delay_10`
    const delay = await redis.get('content', key)
    if (delay) {
      // throw new AuthFailed('请10秒后再发表评论')
    }

    const article = await Article.findOne({
      where: {
        id: data.get('article_id')
      }
    })

    if (!article) {
      throw new NotFound('这篇文章不存在')
    }

    if(article.status != 1){
      throw new AuthFailed('文章状态不支持发布评论');
    }

    let column_user_id;
    if (data.get('column_id')) {
      const comment = await Comment.findOne({
        where: {
          id: data.get('column_id')
        }
      })

      if (!comment) {
        throw new NotFound('回复的评论不存在')
      }

      const user = await User.findOne({
        where: {
          uid: data.get('column_user_id')
        }
      })
      if(!user){
        throw new NotFound('你回复的用户不存在');
      }
      column_user_id = user.id;
    }

    await Comment.create({
      user_id: auth.id,
      content: data.get('content'),
      article_id: data.get('article_id'),
      column_id: data.get('column_id'),
      column_user_id
    })

    await redis.set('content', key, true, 10)
  }

  static async delete(data, ctx) {
    const comment = await Comment.findOne({
      where: {
        id: data.get('id')
      }
    })

    if (!comment) {
      throw new NotFound('评论不存在')
    }

    if(comment.user_id != ctx.auth.id || ctx.auth.scope < ADMIN ){
      throw new AuthFailed('你没有权限删除这条评论')
    }

    await comment.destroy();
  }

  static async getList(data, auth){
    const { page = 1, size = 5, keyword, article_id, user_id, order = 'DESC', column, column_id = null } = data.get();
    const key = `article_comment_page_${page}_article_id_${article_id}_size_${size}_keyword_${keyword}_user_id_${user_id}_order_${order}_column_${column}_column_id_${column_id}`
    let filter = {
      column_id
    };
    if(article_id){
      const article = await Article.findOne({
        where: {
          id: article_id
        }
      })

      if (!article) {
        throw new NotFound('这篇文章不存在')
      }

      filter.article_id = article_id;
    }

    if(keyword){
      filter.content = {
        [Op.like]: `%${xss(keyword)}%`
      }
    }

    if(user_id){
      const user = await User.findOne({
        where: {
          uid: user_id
        }
      })
      if(user){
        filter.user_id = user.id
      }
    }

    let f = false;
    if(column){
      if(!auth){
        throw new AuthFailed('没有权限访问');
      }
      filter.column_user_id = auth.id;
      delete filter.column_id
      f = true;
    }

    // const cache = await redis.get('content', key);
    // if(cache){
    //   const res = JSON.parse(cache);
    //   res.cache = true;
    //   for(let i = 0; i < res.list.length; i++){
    //     let item = res.list[i];
    //     item.like = await getLike('comment', item.id, auth && auth.uid);

    //     for(let j = 0; j < item.column.length; j++){
    //       let column = item.column[j];
    //       column.like = await getLike('comment', item.id, auth && auth.uid);
    //     }
    //   }
    //   return res;
    // }

    const comments = await Comment.findAndCountAll({
      limit: size,
      where: filter,
      offset: (page - 1) * parseInt(size),
      order: [['created_at', order]],
      attributes: {
        exclude: ['deleted_at', 'updated_at', 'user_id', 'column_user_id', f ? '' : 'column_reading']
      },
      include: [
        {
          model: User,
          as: 'user',
          attributes: ['username', 'portrait', 'uid']
        },
        {
          model: Comment,
          as: 'column',
          order: [['created_at', order]],
          attributes: {
            exclude: ['deleted_at', 'updated_at', 'user_id', 'column_user_id']
          },
          limit: size,
        }
      ]
    })

    const result = {
      list: JSON.parse(JSON.stringify(comments.rows)),
      meta: {
        total: comments.count,
        page_size: size,
        current_page: parseInt(page),
        total_pages: Math.ceil(comments.count / size)
      }
    }

    if(f){
      comments.rows.map(async comment => {
        await comment.update({
          column_reading: "true"
        })
      })
    }

    // await redis.set('content', key, JSON.stringify(result), 60);

    for(let i = 0; i < result.list.length; i++){
      let item = result.list[i];
      item.like = await getLike('comment', item.id, auth && auth.id);

      for(let j = 0; j < item.column.length; j++){
        let column = item.column[j];
        column.like = await getLike('comment', item.id, auth && auth.id);
      }
    }

    return result;
  }
}

module.exports = CommentController
